<template>
  <div style="border: 1px solid #ccc; z-index: 99; height: 100%">
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <Editor
      style="height: calc(100% - 80px); min-height: 320px; overflow-y: hidden"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
      @onChange="handleChange"
    />
  </div>

  <UploadModal
    v-if="dialogUploadModal.visible"
    v-model:visible="dialogUploadModal.visible"
    :list="imageList"
    type="image"
    :max="9"
    :compress-size="160"
    @on-complete="dialogUploadModal.complete"
  />
</template>

<script setup lang="ts">
import { onBeforeUnmount, ref, shallowRef, reactive, watch } from 'vue';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import UploadModal from '@/components/UploadModal.vue';
import { InitDrawerOpts, transformPromise } from '@/utils/common';
import { IDomEditor, InsertFnType, SlateElement } from '@wangeditor/editor';

type ImageElement = SlateElement & {
  src: string;
  alt: string;
  url: string;
  href: string;
};

// props
const props = defineProps({
  content: {
    type: String,
    default: ''
  }
});

// emits
const emits = defineEmits(['update:content']);

// 弹窗
const dialogUploadModal = reactive(InitDrawerOpts<{ url: string }>());
const imageList = ref<[]>([]);

const mode = 'default'; // 或 'simple'

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef<IDomEditor>();

// 内容 HTML
const valueHtml = ref('');
watch(
  () => props.content,
  (val, oldVal) => {
    if (val === oldVal) return;
    valueHtml.value = val;
  },
  {
    immediate: true
  }
);

// // 模拟 ajax 异步获取内容
// onMounted(() => {
//   setTimeout(() => {
//     valueHtml.value = props.content;
//   }, 1500);
// });

const toolbarConfig = {
  // 屏蔽某些菜单
  excludeKeys: [
    'todo',
    'emotion',
    'insertLink',
    'group-video',
    'insertTable',
    'codeBlock',
    'divider'
  ]
};
const editorConfig = {
  placeholder: '请输入内容...',

  MENU_CONF: {
    // 插入图片
    insertImage: {
      // 插入图片后回调
      onInsertedImage(_imageNode: ImageElement | null) {
        // 插入图片后自动换行
        editorRef.value?.insertBreak();
      }
    },
    uploadImage: {
      // 自定义选择图片
      async customBrowseAndUpload(insertFn: InsertFnType) {
        dialogUploadModal.visible = true;
        const res = await transformPromise<string[]>(dialogUploadModal);
        (res.result || []).forEach((path: string) => {
          // 最后插入图片
          insertFn(path, path, path);
        });
      }
    }
  }
};

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});

const handleCreated = (editor: IDomEditor) => {
  editorRef.value = editor; // 记录 editor 实例，重要！
};

const handleChange = (editor: IDomEditor) => {
  emits('update:content', editor.getHtml());
};
</script>

<style lang="scss" scoped>
.box-card {
  &.calendar {
    height: 640px;
  }
}
:deep(.el-calendar) {
  .el-calendar__header {
    padding: 16px 20px;
  }
}
</style>
